package com.greateamd.timetableasy.domain;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

import net.sf.gilead.pojo.gwt.LightEntity;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.i18n.client.DateTimeFormat;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.FocusPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.PopupPanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.gwt.user.datepicker.client.CalendarUtil;
import com.greateamd.timetableasy.client.domain.AuthType;
import com.greateamd.timetableasy.client.domain.EventModality;
import com.greateamd.timetableasy.client.domain.EventType;
import com.greateamd.timetableasy.client.mvc.model.Model;
import com.greateamd.timetableasy.client.mvc.view.TimeTableasyPage;
import com.greateamd.timetableasy.client.mvc.view.crud.event.EditEventPage;
import com.greateamd.timetableasy.client.widgets.event.EventPanel;

@SuppressWarnings("serial")
@Entity
@Table(name="events")
public class Event extends LightEntity implements PersistableEntity,Serializable
{

	@Id
	@GeneratedValue
	private Integer id;
	
	@Column(name="enabled",nullable=false)
	private boolean enabled;
	@Column(name="mandatory",nullable=false)
	private boolean mandatory;
	
	@Column(name="label",length=255, nullable=false)
	private String label;
	@Column(name="location",length=255, nullable=false)
	private String location;
	@Column(name="modality",length=255, nullable=true)
	private String modality;
	@Column(name="type",length=255, nullable=false)
	private String type = "";
	
	@Column(name="start_date",nullable=true)
	private Date startDate;
	@Column(name="duration",nullable=false)
	private int duration;

	@Column(name="dispenser",length=150, nullable=true)
	private String dispenser;
	
	public Event()
	{}
	
	public Event(boolean mandatory,String label,String location,EventType type,EventModality modality,Date start,int duration,String dispenser,boolean enabled) 
	{
		this.mandatory = mandatory;
		this.label = label;
		this.location = location;
		if(type != null)
			this.type = type.getText();
		if(modality != null)
			this.modality = modality.getText();
		this.startDate = start;
		this.duration = duration;
		this.dispenser = dispenser;
		this.enabled = enabled;
	}
	
	@Override
	public Integer getId() {
		return id;
	}

	@SuppressWarnings("unused")
	private void setId(Integer id) {
        this.id = id;
    }

	@Override
	public boolean isEnabled() {
		return enabled;
	}

	public boolean isMandatory() {
		return mandatory;
	}

	public String getLabel() {
		return label;
	}

	public String getLocation() {
		return location;
	}

	public Date getStartDate() {
		return startDate;
	}

	public int getDuration() {
		return duration;
	}

	public String getDispenser() {
		return dispenser;
	}

	public void setMandatory(boolean mandatory) {
		this.mandatory = mandatory;
	}

	public void setLabel(String label) {
		this.label = label;
	}

	public void setLocation(String location) {
		this.location = location;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public void setDuration(int duration) {
		this.duration = duration;
	}

	public void setDispenser(String dispenser) {
		this.dispenser = dispenser;
	}

	public String getModality() {
		return modality;
	}


	public String getType() {
		return type;
	}

	public void setEventModality(EventModality modality) {
		this.modality = modality.getText();
	}
	
	@Deprecated
	/**
	 * Use setEventType() instead of
	 */
	public void setModality(String modality) {
		this.modality = modality;
	}

	public void setEventType(EventType type) {
		this.type = type.getText();
	}
	
	@Deprecated
	/**
	 * Use setEventType() instead of
	 */
	public void setType(String type) {
		this.type = type;
	}
	
	public EventModality getEventModality() {
		return EventModality.getEventModalityOf(modality);
	}

	public EventType getEventType() {
		return EventType.getEventTypeOf(type);
	}

	public Widget getIconPanel(final User userViewRequest, final TimeTableasyPage pageViewRequest){
		final FlowPanel panel = new FlowPanel();
		panel.setTitle("Voir l'évènement");
		panel.addStyleName("EventPanel");
		panel.addStyleName(getEventType().getColorStyle(getEventModality()));
		
		panel.add(new HTML(getLabel()));
		panel.add(new HTML(getLocation()));
		// Set color if function of attributes
		if(getEventType().equals(EventType.COURSE)){
			panel.add(new HTML(getModality()));
		}
		// If event have a dispenser
		if(getDispenser()!=null){
			panel.add(new HTML(getDispenser().toString()));
			// If the user who request the widget is the dispenser
			if(getDispenser().equalsIgnoreCase(userViewRequest.getUsername())){
				panel.addStyleName("EventTeacherPanel");
				panel.setTitle("Vous êtes l'intervenant de cet évènement, voir l'évènement");
			}
		}

		// Add click to details functionality
		FocusPanel fp = new FocusPanel(panel);
		fp.addClickHandler(new ClickHandler() {
			@Override
			public void onClick(ClickEvent arg0) {
				final PopupPanel p = new PopupPanel(true,false);
				p.setAnimationEnabled(true);
				p.setGlassEnabled(true);

				// This event can be edited ?
				boolean canBeEdit = false;
				switch(pageViewRequest){
				case PLANNING_UNIVERSITY:
					if(getEventType().equals(EventType.UNIVERSITY) && userViewRequest.getAuths().contains(new Auth(userViewRequest,AuthType.ROLE_ADMIN))){
						canBeEdit = true;
					}
					break;
				case PLANNING_CAMPUS:
					if(getEventType().equals(EventType.CAMPUS) && userViewRequest.getAuths().contains(new Auth(userViewRequest,AuthType.ROLE_CAMPUS_MANAGER))){
						canBeEdit = true;
					}
					break;
				case PLANNING_PROMOTION:
					if((getEventType().equals(EventType.PROMOTION)|| getEventType().equals(EventType.COURSE)) && userViewRequest.getAuths().contains(new Auth(userViewRequest,AuthType.ROLE_CAMPUS_MANAGER))){
						canBeEdit = true;
					}
					break;
				case PLANNING_STUDYPERIOD:
					if((getEventType().equals(EventType.STUDY_PERIOD)|| getEventType().equals(EventType.COURSE)) ){
						if( userViewRequest.getAuths().contains(new Auth(userViewRequest,AuthType.ROLE_ADMIN)) 
   						 || userViewRequest.getAuths().contains(new Auth(userViewRequest,AuthType.ROLE_CAMPUS_MANAGER))){
							canBeEdit = true;
						}
					}
					break;
				case PLANNING_USER:
					if(getEventType().equals(EventType.USER) && userViewRequest.getAuths().contains(new Auth(userViewRequest,AuthType.ROLE_USER))){
						canBeEdit = true;
					}
					break;
				default:
					canBeEdit = false;
					break;
				}
				
				//If user haven't auth match planning type, show eventpanel
				if(!canBeEdit){
					p.setWidget(new EventPanel(true,Event.this));
				//Else set EditEventPage
				} else {
					p.setAutoHideEnabled(false);
					final HorizontalPanel hp = new HorizontalPanel();
					hp.add(new EditEventPage<Model>(Event.this));
					hp.add(new Button("Close",new ClickHandler() {
						@Override
						public void onClick(ClickEvent arg0) {
							p.hide();
						}
					}));
					p.setWidget(hp);
				}
				p.show();
				p.center();
			}
		});
		return fp;
	}

	@Override
	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}
	
	
	@Override
	public String toString() {
		return getLabel() +" " + getModality() + " " + getLocation();
	}

	public String getICalAsHtml() {
		DateTimeFormat dateFormater = DateTimeFormat.getFormat("yMMdd'T'kkmmss");
		Date s = getStartDate();
		Date e = CalendarUtil.copyDate(s);
		e.setHours(s.getHours()+getDuration());
		String dtstart = dateFormater.format(s);
		String dtend = dateFormater.format(e);
		return "BEGIN:VCALENDAR<br/>"+
					"VERSION:1.0<br/>"+
					"BEGIN:VEVENT<br/>"+
					"DTSTART:"+dtstart+"<br/>"+
					"DTEND:"+dtend+"<br/>"+
					"SUMMARY:"+getLabel()+"<br/>"+
					"LOCATION:"+getLocation()+"<br/>"+
					"DESCRIPTION:<br/>"+
					"PRIORITY:3<br/>"+
					"END:VEVENT<br/>"+
					"END:VCALENDAR";
	}
	
	@Override
	public boolean equals(Object obj) {
		if( obj != null && obj instanceof Event ){
			Event e = (Event)obj;
			if(e.getId()==null){
				return false;
			} else if(e.getId().equals(getId())){
				return true;
			}
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		if(getId()==null)
			return super.hashCode();
		else
			return 16*getId().hashCode();
	}
}
